package com.ksyun.campus.client;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ksyun.campus.client.domain.*;
import com.ksyun.campus.client.fetcher.MetaServiceFetcher;
import lombok.AllArgsConstructor;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.io.entity.StringEntity;

import java.io.IOException;
import java.util.List;
import java.util.regex.Pattern;

public class EFileSystem extends FileSystem{
    private MetaServiceFetcher metaServiceFetcher;
    public EFileSystem() throws IOException {
        this("default");
        metaServiceFetcher=new MetaServiceFetcher();
    }

    public EFileSystem(String fileSystemName) {
        this.defaultFileSystemName = fileSystemName;
    }

    public FSInputStream open(String path) throws IOException {
        //判断路径是否符合规范
        //判断路径是否符合规范
        if (!isValidPath(path)){
            System.out.println(" 路径不符合规范!");
        }

        return null;
    }
    public FSOutputStream create(String path){


        return null;
    }

    public boolean mkdir(String path) throws IOException {
        //判断路径是否符合规范
        if (!isValidPath(path)){
            System.out.println(" 路径不符合规范!");
            return false;
        }

        MetaServerMsg master = findMaster();
        if (master!=null){
            //调用远程的删除服务
            //master节点非空，拿出相关的数据，进行拼接调用
            String host = master.getHost();
            int port = master.getPort();
            //TODO 调用远程的mkdir接口，接收返回值并且解析
            String url="http://"+host+":"+port+"/mkdir?path="+path;
            HttpPost httpPost = new HttpPost(url);
            httpPost.setHeader("fileSystemName",this.defaultFileSystemName);
            CloseableHttpClient httpClient = HttpClients.createDefault();
            try {
                CloseableHttpResponse response = httpClient.execute(httpPost);
                HttpEntity responseEntity = response.getEntity();
                if (responseEntity != null) {
                    // 解析返回值
                    ObjectMapper objectMapper = new ObjectMapper();
                    ApiResponse<String> apiResponse = objectMapper.readValue(
                            responseEntity.getContent(),
                            new TypeReference<ApiResponse<String>>() {}
                    );
                    // 检查 API 响应的状态
                    if (apiResponse.getCode() == 200) { // 假设 200 是成功状态码
                        return true;
                    } else {
                        System.err.println("API 错误: " + apiResponse.getMsg());
                        return false; // 或者抛出异常
                    }
                }
                response.close();
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                httpClient.close();
            }
        }
        return false;
    }
    public boolean delete(String path) throws IOException {
        //判断路径是否符合规范
        if (!isValidPath(path)){
            System.out.println(" 路径不符合规范!");
            return false;
        }

        MetaServerMsg master = findMaster();
        if (master!=null){
            //调用远程的删除服务
            //master节点非空，拿出相关的数据，进行拼接调用
            String host = master.getHost();
            int port = master.getPort();
            //TODO 调用远程的delete接口，接收返回值并且解析
            String url="http://"+host+":"+port+"/delete?path="+path;
            HttpPost httpPost = new HttpPost(url);
            httpPost.setHeader("fileSystemName",this.defaultFileSystemName);
            CloseableHttpClient httpClient = HttpClients.createDefault();
            try {
                CloseableHttpResponse response = httpClient.execute(httpPost);
                HttpEntity responseEntity = response.getEntity();
                if (responseEntity != null) {
                    // 解析返回值
                    ObjectMapper objectMapper = new ObjectMapper();
                    ApiResponse<String> apiResponse = objectMapper.readValue(
                            responseEntity.getContent(),
                            new TypeReference<ApiResponse<String>>() {}
                    );
                    // 检查 API 响应的状态
                    if (apiResponse.getCode() == 200) { // 假设 200 是成功状态码
                        return true;
                    } else {
                        System.err.println("API 错误: " + apiResponse.getMsg());
                        return false; // 或者抛出异常
                    }
                }
                response.close();
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                httpClient.close();
            }
        }
        return false;
    }
    public StatInfo getFileStats(String path) throws IOException {
        if (!isValidPath(path)){
            System.out.println("路径不合法!");
            return null;
        }
        //找到master
        MetaServerMsg master = findMaster();
        if (master!=null){
            //master节点非空，拿出相关的数据，进行拼接调用
            String host = master.getHost();
            int port = master.getPort();
            //TODO 调用远程的stats接口，接收返回值并且解析
            String url="http://"+host+":"+port+"/stats?path="+path;
            HttpPost httpPost = new HttpPost(url);
            httpPost.setHeader("fileSystemName",this.defaultFileSystemName);

            CloseableHttpClient httpClient = HttpClients.createDefault();
            try {
                CloseableHttpResponse response = httpClient.execute(httpPost);
                HttpEntity responseEntity = response.getEntity();
                if (responseEntity != null) {
                    // 解析返回值
                    ObjectMapper objectMapper = new ObjectMapper();
                    ApiResponse<StatInfo> apiResponse = objectMapper.readValue(
                            responseEntity.getContent(),
                            new TypeReference<ApiResponse<StatInfo>>() {}
                    );
                    // 检查 API 响应的状态
                    if (apiResponse.getCode() == 200) { // 假设 200 是成功状态码
                        return apiResponse.getData();
                    } else {
                        System.err.println("API 错误: " + apiResponse.getMsg());
                        return null; // 或者抛出异常
                    }
                }
                response.close();
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                httpClient.close();
            }
        }
        return null;
    }
    public List<StatInfo> listFileStats(String path) throws IOException {
        //判断路径参数是否符合规范
        if (!isValidPath(path)){
            //不符合规范
            //TODO  处理不符合规范的情况
            System.out.println("输入的路径不规范!");
            return null;
        }


        //找到master
        MetaServerMsg master = findMaster();
        if (master!=null){
            //master节点非空，拿出相关的数据，进行拼接调用
            String host = master.getHost();
            int port = master.getPort();
            //TODO 调用远程的listdir接口，接收返回值并且解析
            String url="http://"+host+":"+port+"/listdir?path="+path;

            HttpPost httpPost = new HttpPost(url);
            httpPost.setHeader("fileSystemName",this.defaultFileSystemName);

            CloseableHttpClient httpClient = HttpClients.createDefault();
            try {
                CloseableHttpResponse response = httpClient.execute(httpPost);
                HttpEntity responseEntity = response.getEntity();
                if (responseEntity != null) {
                    // 解析返回值
                    ObjectMapper objectMapper = new ObjectMapper();
                    ApiResponse<List<StatInfo>> apiResponse = objectMapper.readValue(
                            responseEntity.getContent(),
                            new TypeReference<ApiResponse<List<StatInfo>>>() {}
                    );

                    // 检查 API 响应的状态
                    if (apiResponse.getCode() == 200) { // 假设 200 是成功状态码
                        return apiResponse.getData();
                    } else {
                        System.err.println("API 错误: " + apiResponse.getMsg());
                        return null; // 或者抛出异常
                    }
                }
                 response.close();
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                httpClient.close();
            }
        }
        return null;
    }
    public ClusterInfo getClusterInfo(){

        //TODO  改为具体的路径值
        //具体节点的位置
        String masterMetaServerPath="";
        String slaveMetaServerPath="";
        //父节点的路径
        String dataServerPath="";

        MetaServerMsg masterMetaServer= metaServiceFetcher.getMetaServiceInfo(masterMetaServerPath);
        MetaServerMsg slavermetaService = metaServiceFetcher.getMetaServiceInfo(slaveMetaServerPath);
        List<DataServerMsg> dataServer = metaServiceFetcher.getDataServer(dataServerPath);
        ClusterInfo clusterInfo=new ClusterInfo(masterMetaServer,slavermetaService,dataServer);
        return clusterInfo;
    }

    // 定义非法字符的正则表达式
    private static final Pattern ILLEGAL_CHARACTERS = Pattern.compile("[<>:\"/\\|?*]");

    public static boolean isValidPath(String path) {
        // 检查路径是否为 null 或空字符串
        if (path == null || path.isEmpty()) {
            return false;
        }

        // 检查路径是否以斜杠开头
        if (!path.startsWith("/")) {
            return false;
        }

        // 分隔路径部分
        String[] parts = path.split("/");

        // 遍历各个部分，进行检查
        for (String part : parts) {
            if (part.isEmpty() || ILLEGAL_CHARACTERS.matcher(part).find()) {
                return false; // 发现空部分或非法字符
            }
        }

        // 可根据需要加上长度检查
        if (path.length() > 255) { // 假设最大长度为255
            return false;
        }

        return true; // 路径符合规范
    }

    //判断MetaService的主节点
    private  MetaServerMsg findMaster(){
        //TODO 传入MetaService的节点路径值
        //TODO  获取Service来进行判断调用
        //具体节点的位置
        String masterPath="";
        String slavePath="";
        //判断
        MetaServerMsg metaServiceInfo = metaServiceFetcher.getMetaServiceInfo(masterPath);
        if (metaServiceInfo!=null){
            return metaServiceInfo;
        }else {
            MetaServerMsg metaServiceInfo1 = metaServiceFetcher.getMetaServiceInfo(slavePath);
            if (metaServiceInfo1!=null){
                return metaServiceInfo1;
            }else {
                return null;
            }
        }
    }
}
